/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"

#include "an_曲线.h"
#include "curve.h"
#include "core/shader_curve.h"
#include "core/属性.h"

static std::set<S_曲线通道*> g动画曲线;


S_曲线* f_an_创建曲线A() {
	S_曲线* curve = (S_曲线*)f_core_array_new(0, sizeof(S_CurvePoint2));
	return curve;
}

void f_an_销毁曲线A(S_曲线* curve) {
	f_core_array_free((S_Array*)curve);
}




S_曲线通道* f_an_创建曲线通道(uint32 通道数量) {
	S_曲线通道* 曲线通道 = (S_曲线通道*)malloc(sizeof(S_曲线通道));
	曲线通道->曲线 = (S_曲线**)calloc(通道数量, sizeof(S_曲线*));
	曲线通道->count = 通道数量;
	曲线通道->name[0] = '\0';
	曲线通道->ObPtr = nullptr;

	for (uint32 i = 0; i < 通道数量; ++i) {
		曲线通道->曲线[i] = f_an_创建曲线A();
	}

	return 曲线通道;
}

void f_an_销毁曲线通道(S_曲线通道* curve) {
	for (uint32 i = 0; i < curve->count; ++i) {
		f_an_销毁曲线A(curve->曲线[i]);
	}

	free(curve->曲线);
	free(curve);
}

S_曲线通道* f_an_拷贝曲线通道(const S_曲线通道* 源) {
	S_曲线通道* 新通道 = f_an_创建曲线通道(源->count);

	for (uint32 i = 0; i < 源->count; ++i) {
		新通道->曲线[i] = (S_曲线*)f_core_array_from((S_Array*)(源->曲线[i]));
	}
	
	return 新通道;
}


S_动画曲线组* f_an_创建曲线层() {
	S_动画曲线组* curve = (S_动画曲线组*)malloc(sizeof(S_动画曲线组));
	curve->曲线通道 = f_core_createList();
	curve->通道num = 0;
	return curve;
}

void f_an_销毁曲线层(S_动画曲线组* 曲线通道) {
	f_core_releaseList(曲线通道->曲线通道);
	曲线通道->通道num = 0;
	free(曲线通道);
}

S_动画曲线组* f_an_拷贝曲线层(S_动画曲线组* 源) {
	S_动画曲线组* 新层 = (S_动画曲线组*)malloc(sizeof(S_动画曲线组));
	新层->曲线通道 = f_core_copyList(源->曲线通道);
	新层->通道num = 源->通道num;
	return 新层;
}

S_曲线通道* f_an_添加曲线通道(S_动画曲线组* 曲线层, uint32 通道数量) {
	S_曲线通道* 曲线通道 = f_an_创建曲线通道(通道数量);

	f_core_addListEndItem(曲线层->曲线通道, 曲线通道);
	++(曲线层->通道num);
	return 曲线通道;
}

void f_an_添加曲线通道(S_动画曲线组* 曲线层, S_曲线通道* 曲线通道) {
	f_core_addListEndItem(曲线层->曲线通道, 曲线通道);
	++(曲线层->通道num);
}

void f_an_清除曲线通道(S_动画曲线组* 曲线层) {
	f_core_list_clear(曲线层->曲线通道);
	曲线层->通道num = 0;
}

//void f_an_添加曲线点(S_曲线通道* 曲线通道, float32 时间, float32 值, const vec2& 左手柄, const vec2& 右手柄) {
//	S_CurvePoint* point = (S_CurvePoint*)malloc(sizeof(S_CurvePoint));
//	point->L_point = 左手柄;
//	point->R_point = 右手柄;
//	point->value = { 时间, 值 };
//	point->ID_Color = { 0, f_PackData4X8({0,0,0,255}) };
//	f_core_addListEndItem(曲线通道->point, point);
//	++(曲线通道->count);
//}

void f_an_添加钳制曲线点(S_曲线* 曲线, const vec2& value, const vec2& 左手柄, const vec2& 右手柄, uint32 ID, const S_RGBA8UI& color) {
	
	S_CurvePoint2 point;// = (S_曲线点*)malloc(sizeof(S_曲线点));
	point.L_point = 左手柄;
	point.R_point = 右手柄;
	point.value = value;
	point.ID_Color = { ID, f_PackData4X8(color) };
	point.Select_Type = {0,0};
	assert(point.ID_Color.x < 1000);
	if (point.value.y > 1) point.value.y = 1;

	f_core_array_push_back((S_Array*)曲线, (uint8*)&point, false);
	//auto a = 曲线->point[曲线->count - 1];
}

void f_an_添加曲线点(S_曲线* 曲线, const vec2& value, const vec2& 左手柄, const vec2& 右手柄, uint32 ID, const S_RGBA8UI& color) {
	S_CurvePoint2 point;// = (S_曲线点*)malloc(sizeof(S_曲线点));
	point.L_point = 左手柄;
	point.R_point = 右手柄;
	point.value = value;
	point.ID_Color = { ID, f_PackData4X8(color) };
	point.Select_Type = {0,0};

	f_core_array_push_back((S_Array*)曲线, (uint8*)&point, false);
	auto a = 曲线->point[曲线->count - 1];
}

void f_an_删除曲线点(S_曲线* 曲线, int32 time) {
	for (int32 i = 0; i < 曲线->count; ++i) {
		if (曲线->point[i].value.x == time) {
			f_core_array_erase((S_Array*)曲线, i);
			break;
		}
	}
}



float32 f_an_曲线插值(S_CurvePoint2* left, S_CurvePoint2* right) {
	return left->value.x + (left->value.x - right->value.x);
}


vec3 f_an_曲线值(const S_曲线通道* 通道, float32 时间) {
	vec3 value = {};
	

	uint32 t = 0;
	if (通道->count < 3) return value;

	float32* value_ptr = (float32*)&value;

	for (uint32 i = 0; i < 通道->count; ++i) {
		S_曲线& curve = *(通道->曲线[i]);

		//value_ptr[i] = f_an_曲线采样(时间, *cuvre);
		//value_ptr[i] = f_graph_钳制曲线采样(时间, *cuvre);
		if (curve.count) {
			if (时间 < curve.point[0].value.x) {
				value_ptr[i] = curve.point[0].value.y;
				continue;
			}

			bool 采样末尾 = true;
			int32 num = curve.count - 1;

			for (uint32 k = 0; k < num; ++k) {
				S_CurvePoint2* 曲线点 = &(curve.point[k]);
				S_CurvePoint2* 后一个曲线点 = &curve.point[k + 1];

				if (时间 < 后一个曲线点->value.x) {
					float32 步数 = 时间 - 曲线点->value.x;
					float32 间隔 = (后一个曲线点->value.x - 曲线点->value.x);
					if (步数 < 0 || 间隔 < 0.0000001) continue;
					步数 = 步数 / 间隔;

					vec2 value = f_curve_cal_point(*曲线点, *后一个曲线点, 步数);

					value_ptr[i] = value.y;
					采样末尾 = false;
					break;
				}
			}

			if (采样末尾) {
				value_ptr[i] = curve.point[curve.count - 1].value.y;
			}
		}
	}

	return value;
}

//S_CurvePoint* f_an_get曲线点(S_曲线通道* 通道曲线, uint32 id) {
//	//return DEF_曲线点(f_core_getItem(通道曲线->point, id));
//
//	uint32 i = 0;
//	DEF_FOR_LIST(曲线点, 通道曲线->point) {
//		if (i == id) {
//			return DEF_曲线点(曲线点);
//		}
//		++i;
//	}
//	return nullptr;
//}
//
//void f_an_曲线值排序(S_曲线通道* 通道曲线) {
//	if (通道曲线->count < 2) return;
//
//	
//
//	uint32 i = 0;
//	for (uint32 i = 0; i < 通道曲线->count; ++i) {
//		auto* point = 通道曲线->point;
//
//		bool 没有交换 = true;
//		DEF_FOR_LIST(曲线点, point->ptr_尾) {
//			if (DEF_曲线点(point)->value.x > DEF_曲线点(曲线点)->value.x) {
//				f_core_swapItem(point, 曲线点);
//				没有交换 = false;
//			}
//			else {
//				//不是初始元素了 -> point->prt_尾
//				point = 曲线点;
//			}
//
//			
//		}
//
//		DEF_FOR_LIST_反向(曲线点, point) 通道曲线->point = 曲线点;
//		
//		if (没有交换) break;
//	}
//	
//}

S_CurvePoint2* f_an_get曲线点A(S_曲线* curve, int32 id) {
	for (uint32 i = 0; i < curve->count; ++i) {
		if (curve->point[i].ID_Color.x == id) {
			return &(curve->point[i]);
		}
	}
	return nullptr;
}

static bool f_钳制曲线点序列排序(S_CurvePoint2* s, S_CurvePoint2* e) {
	//if (s->ID_Color.x == 0 || e->ID_Color.x == 1) return false;
	//if (s->ID_Color.x == 1) return true;
	if (s->value.x > e->value.x) return true;
	return false;
}
void f_an_钳制曲线值排序(S_曲线* 曲线) {
	f_core_array_sort((S_Array*)曲线, (fn_array_sort)f_钳制曲线点序列排序);
}

static bool f_曲线点序列排序(S_CurvePoint2* s, S_CurvePoint2* e) {
	if (s->value.x > e->value.x) return true;
	return false;
}
void f_an_曲线值排序(S_曲线* 曲线) {
	f_core_array_sort((S_Array*)曲线, (fn_array_sort)f_曲线点序列排序);
}


int32 f_an_移除曲线重合点(S_曲线* 曲线, S_CurvePoint2* point, float32 最小距离) {
	int32 id = -1;
	for (uint32 i = 1; i < 曲线->count - 1; ++i) {
		if (曲线->point[i].ID_Color.x != point->ID_Color.x) {

			vec2 dir = 曲线->point[i].value - point->value;
			float32 dis = vec_len(dir);
			if (dis < 最小距离) {
				id = 曲线->point[i].ID_Color.x;
				f_core_array_erase((S_Array*)曲线, i);
				return id;
			}
		}
	}
	return id;
}

//void f_an_自动控制点(S_曲线通道* 通道曲线) {
//	if (通道曲线->count < 2) return;
//
//	
//	auto* point = 通道曲线->point;
//
//	vec2 头点坐标 = DEF_曲线点(point)->value;
//
//	DEF_FOR_LIST(曲线点, point->ptr_尾) {
//		vec2 中点坐标 = DEF_曲线点(曲线点)->value;
//
//		vec2 尾点坐标;
//		if (曲线点->ptr_尾) {
//			尾点坐标 = DEF_曲线点(曲线点->ptr_尾)->value;
//		}
//		else {
//			尾点坐标 = 中点坐标;
//		}
//
//		vec2 控制柄方向 = vec_normalize(尾点坐标 - 头点坐标);
//
//
//		float32 控制点距离 = 中点坐标.x - 头点坐标.x;
//		DEF_曲线点(曲线点)->L_point = 中点坐标 - (控制柄方向 * (控制点距离 * 0.5));
//
//		控制点距离 = 尾点坐标.x - 中点坐标.x;
//		DEF_曲线点(曲线点)->R_point = 中点坐标 + (控制柄方向 * (控制点距离 * 0.5));
//
//		头点坐标 = 中点坐标;
//	}
//
//}

static void f_计算钳制曲线控制点(S_曲线* p0, S_曲线* p1, S_曲线* p2) {

}

void f_an_钳制曲线自动控制点(S_曲线* 曲线) {
	int32 num = 曲线->count;
	int32 i = 0;

	if (num <= 2) {
		for (; i < num; ++i) {
			S_CurvePoint2* point = &(曲线->point[i]);
			point->L_point = point->value;
			point->R_point = point->value;
		}
		return;
	}

	float32 平滑度 = 0.9;
	num -= 2;

	
	for (; i < num; ++i) {
		S_CurvePoint2* 前端 = &(曲线->point[i]);
		S_CurvePoint2* 中端 = &(曲线->point[i+1]);
		S_CurvePoint2* 后端 = &(曲线->point[i+2]);

		vec2 L1 = (前端->value - 中端->value);
		vec2 L2 = (后端->value - 中端->value);

		float32 l1_len = fabs(L1.x);
		float32 l2_len = fabs(L2.x);

		vec2 d1 = L1 * 0.5 + 中端->value;
		vec2 d2 = L2 * 0.5 + 中端->value;
		vec2 控制点方向 = d2 - d1;

		float32 控制点方向长度 = vec_normalize(&控制点方向);
		float32 比例 = 1;
		if (l2_len >= l1_len) {
			比例 = (l1_len / l2_len);

			float32 左边控制点长度 = 控制点方向长度 * 0.5 * 比例;
			中端->L_point = 中端->value - 控制点方向 * 左边控制点长度 * 平滑度 ;
			中端->R_point = 中端->value + 控制点方向 * (控制点方向长度 - 左边控制点长度) * 平滑度;
		}
		else {
			比例 = (l2_len / l1_len);
			float32 左边控制点长度 = 控制点方向长度 * 0.5 * 比例;
			中端->L_point = 中端->value - 控制点方向 * (控制点方向长度 - 左边控制点长度) * 平滑度;
			中端->R_point = 中端->value + 控制点方向 * 左边控制点长度 * 平滑度;
		}
	}

	曲线->point[0].L_point = 曲线->point[0].value - vec_normalize(曲线->point[1].L_point - 曲线->point[0].value)*2;
	曲线->point[0].R_point = 曲线->point[0].value+0.001;
	曲线->point[num+1].L_point = 曲线->point[num+1].value-0.001;
	曲线->point[num+1].R_point = vec_normalize(曲线->point[num+1].value - 曲线->point[num].R_point) + 曲线->point[num+1].value;
	return;


	for (int32 i = 1; i <= num; ++i) {
		if (i == 1) {
			S_CurvePoint2* 中端 = &(曲线->point[i]);
			S_CurvePoint2* 后端 = &(曲线->point[i+1]);

			float32 k = (后端->value.y - 中端->value.y) / (后端->value.x - 中端->value.x);
			float32 b = 中端->value.y - k * 中端->value.x;

			中端->R_point.x = 中端->value.x + (后端->value.x - 中端->value.x) * 0.3;
			中端->R_point.y = 中端->R_point.x * k + b;
			//中端->R_point.y = 中端->value.y;
		}
		else if (i == num) {
			S_CurvePoint2* 前端 = &(曲线->point[i-1]);
			S_CurvePoint2* 中端 = &(曲线->point[i]);

			float32 k = (中端->value.y - 前端->value.y) / (中端->value.x - 前端->value.x);
			float32 b = 中端->value.y - k * 中端->value.x;

			中端->L_point.x = 中端->value.x - (中端->value.x - 前端->value.x) * 0.4;
			中端->L_point.y = 中端->L_point.x * k + b;

			
			//中端->R_point.x += 2;
			{
				S_CurvePoint2* 后端 = &(曲线->point[i + 1]);

				vec2 v = 中端->value - 中端->L_point;
				中端->R_point = 中端->value + v * 3;

				后端->value = 中端->R_point;
				后端->L_point = 中端->R_point;
			}
		}
		else {
			S_CurvePoint2& 前端 = (曲线->point[i - 1]);
			S_CurvePoint2& 中端 = (曲线->point[i]);
			S_CurvePoint2& 后端 = (曲线->point[i + 1]);

			float32 k = (后端.value.y - 前端.value.y) / (后端.value.x - 前端.value.x);
			float32 b = 中端.value.y - k * 中端.value.x;

			中端.L_point.x = 中端.value.x - (中端.value.x - 前端.value.x) * 平滑度;
			中端.L_point.y = 中端.L_point.x * k + b;

			中端.R_point.x = 中端.value.x + (后端.value.x - 中端.value.x) * 平滑度;
			中端.R_point.y = 中端.R_point.x * k + b;
		}

	}

	{
		S_CurvePoint2* 前端 = &(曲线->point[0]);
		S_CurvePoint2* 中端 = &(曲线->point[1]);
		S_CurvePoint2* 后端 = &(曲线->point[2]);

		vec2 v = vec_normalize(后端->L_point - 中端->value);
		中端->L_point = 中端->value - v * 3;

		前端->value = 中端->L_point;
		前端->L_point = 前端->value;
		前端->R_point = 中端->value;
	}

	return;

}

void f_an_自动控制点(S_曲线* 曲线) {
	int32 num = 曲线->count;
	if (num<2) return;


	float32 平滑度 = 0.4;

	for (int32 i = 0; i < num; ++i) {
		switch (曲线->point[i].Select_Type.y) {
		case DEF_CONTORL_POINT_AUTO:
			if (i == 0) {
				S_CurvePoint2* 中端 = &(曲线->point[i]);
				S_CurvePoint2* 后端 = &(曲线->point[i + 1]);

				中端->R_point.x = 中端->value.x + (后端->value.x - 中端->value.x) * 平滑度;
				中端->R_point.y = 中端->value.y;
				中端->L_point = 中端->value;
				//中端->ID_Color.x = i + 1;
			}
			else if (i == num - 1) {
				S_CurvePoint2* 前端 = &(曲线->point[i - 1]);
				S_CurvePoint2* 中端 = &(曲线->point[i]);

				中端->L_point.x = 中端->value.x - (中端->value.x - 前端->value.x) * 平滑度;
				中端->L_point.y = 中端->value.y;
				中端->R_point = 中端->value;
				//中端->ID_Color.x = 0xffffffff;
			}
			else {
				S_CurvePoint2& 前端 = (曲线->point[i - 1]);
				S_CurvePoint2& 中端 = (曲线->point[i]);
				S_CurvePoint2& 后端 = (曲线->point[i + 1]);

				float32 k = (后端.value.y - 前端.value.y) / (后端.value.x - 前端.value.x);
				float32 b = 中端.value.y - k * 中端.value.x;

				中端.L_point.x = 中端.value.x - (中端.value.x - 前端.value.x) * 平滑度;
				中端.L_point.y = 中端.L_point.x * k + b;

				中端.R_point.x = 中端.value.x + (后端.value.x - 中端.value.x) * 平滑度;
				中端.R_point.y = 中端.R_point.x * k + b;
			}
			break;

		case DEF_CONTORL_POINT_FREE:
			
			break;

		case DEF_CONTORL_POINT_ALGNED:
			break;

		case DEF_CONTORL_POINT_VECTOR:
			S_CurvePoint2* 中端 = &(曲线->point[i]);
			S_CurvePoint2* 后端;

			if (i == 0) {
				中端->L_point = 中端->value;
				后端 = &(曲线->point[i + 1]);
			}
			else if (i >= num - 1) {
				后端 = &(曲线->point[i]);
				后端->R_point = 中端->value;
			}
			else {
				后端 = &(曲线->point[i + 1]);
			}

			vec2 v = 后端->value - 中端->value;

			中端->R_point = 中端->value + v * 0.3;
			后端->L_point = 后端->value - v * 0.3;

			
			break;
		}
		

	}
}

float32 f_an_曲线采样(float32 采样位置, const S_曲线& curve) {
	return float32();
}


int32 f_an_查找重叠帧(S_曲线* 曲线, float32 帧时间) {
	for (int32 i = 0; i < 曲线->count; ++i) {
		if (fabs(曲线->point[i].value.x - 帧时间) < 0.3) {
			return i;
		}
	}
	return -1;
}



void f_an_Load(S_曲线* curve, FILE* f) {
	f_core_array_load((S_Array*)curve, f);
}

void f_an_Save(S_曲线* curve, FILE* f) {
	f_core_array_save((S_Array*)curve, f);
}





S_曲线通道* f_an_Load通道(FILE* f) {
	uint32 num = 0;
	fread(&num, sizeof(uint32), 1, f);

	S_曲线通道* curve = nullptr;

	if (num) {
		curve = f_an_创建曲线通道(num);
		fread(curve->name, sizeof(uint8), 32, f);

		for (uint32 i = 0; i < num; ++i) {
			f_an_Load(curve->曲线[i], f);
		}
	}
	
	return curve;
}

void f_an_Save通道(S_曲线通道* curve, FILE* f) {
	if (curve && curve->count) {
		fwrite(&(curve->count), sizeof(uint32), 1, f);

		if (curve->count) {
			fwrite(curve->name, sizeof(uint8), 32, f);

			for (uint32 i = 0; i < curve->count; ++i) {
				f_an_Save(curve->曲线[i], f);
			}
		}
	}
	else {
		uint32 num = 0;
		fwrite(&num, sizeof(uint32), 1, f);
	}
}








const uint8* f_an_Load通道(S_曲线通道** curve, const uint8* 块) {
	uint32 num = 0;
	块 = f_文件块_读数据块(块, num);

	if (num) {
		curve[0] = f_an_创建曲线通道(num);
		块 = f_文件块_读数据块2((uint8*)curve[0]->name, 块, 32);
		
		for (uint32 i = 0; i < num; ++i) {
			块 = f_an_解(curve[0]->曲线[i], 块);
		}
	}

	return 块;
}

void f_an_Save通道(S_曲线通道* curve, S_UI8Array* 块) {
	if (curve && curve->count) {
		f_core_array_push_back_block((S_Array*)块, (uint8*)&curve->count, sizeof(uint32));
		
		if (curve->count) {
			f_文件块_写数据块(块, (uint8*)curve->name, 32);

			for (uint32 i = 0; i < curve->count; ++i) {
				f_an_包(curve->曲线[i], 块);
			}
		}
	}
	else {
		uint32 num = 0;
		f_core_array_push_back_block((S_Array*)块, (uint8*)&num, sizeof(uint32));
	}
}





